package com.xx.bysj.service.imp;

import com.github.pagehelper.PageHelper;
import com.xx.bysj.dto.HnMenu;
import com.xx.bysj.dto.HnRole;
import com.xx.bysj.dto.HnRoleMenu;
import com.xx.bysj.dto.HnUser;
import com.xx.bysj.dto.Menu;
import com.xx.bysj.dto.TreeDto;
import com.xx.bysj.mapper.HnMenuMapper;
import com.xx.bysj.mapper.HnRoleMapper;
import com.xx.bysj.mapper.HnRoleMenuMapper;
import com.xx.bysj.service.RoleService;
import com.xx.bysj.utils.NumberUtils;
import com.xx.bysj.utils.RedisCacheUtils;
import com.xx.bysj.utils.RedisConstants;
import com.xx.bysj.utils.Result;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl implements RoleService {

    @Autowired
    private HnRoleMapper roleMapper;

    @Autowired
    private HnMenuMapper menuMapper;

    @Autowired
    private HnRoleMenuMapper roleMenuMapper;

    @Autowired
    private RedisCacheUtils redisCacheUtils;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result query(HnRole role, int page, int limit) {
        PageHelper.startPage(page,limit);
        List<HnRole> roleList = roleMapper.selectByRoleName(role);
        return Result.querySuccess(roleList,roleList.size());
    }

    @Override
    public Map<String, Object> getMenuTreeMap(Integer id) {
        Map<String, Object> treeMap = new HashMap<>();

        List<Integer> treeIdList = menuMapper.selectById(id);
        // 菜单List集合
        List<HnMenu> menuList = menuMapper.selectAdminMenu();
        // id不为空表示为update页面获取信息
        if (null != id) {
            for (HnMenu menu : menuList) {
                menu.setChecked(false);
                for (Integer treeId : treeIdList) {
                    if (treeId.equals(menu.getId())) {
                        menu.setChecked(true);
                        // 找到相同的id就退出循环减少循环次数
                        break;
                    }
                }
            }
        }else {
            for (HnMenu menu : menuList) {
                menu.setChecked(false);
            }
        }
        //第一层menu
        List<HnMenu> firstMenuList = new ArrayList<>();
        //第二层menu
        List<HnMenu> secondMenuList = new ArrayList<>();
        //第三层menu
        List<HnMenu> thirdMenuList = new ArrayList<>();
        // 对查询出来的菜单进行分类
        for (HnMenu menu : menuList) {
            if (menu.getSort().equals(NumberUtils.ZERO)) {
                // -2 为横向菜单为第一层菜单
                firstMenuList.add(menu);
            } else if (menu.getSort().equals(NumberUtils.ONE)) {
                // -1 为纵向菜单为第二层菜单
                secondMenuList.add(menu);
            } else if (menu.getSort().equals(NumberUtils.TWO)) {
                // 0 为纵向菜单细分菜单为第三层菜单
                thirdMenuList.add(menu);
            }
        }

        List<TreeDto> treeList = new ArrayList<>();
        // 第一次头
        for (HnMenu menu : firstMenuList) {
            TreeDto firstTree = new TreeDto();
            firstTree.setChecked(menu.getChecked());
            firstTree.setId(menu.getId());
            firstTree.setTitle(menu.getTitle());
            List<TreeDto> secondTreeList = new ArrayList<>();
            for (HnMenu secondMenu : secondMenuList ) {
                if (secondMenu.getPid().equals(menu.getId())) {
                    TreeDto secondTree = new TreeDto();
                    secondTree.setTitle(secondMenu.getTitle());
                    secondTree.setId(secondMenu.getId());
                    secondTree.setChecked(secondMenu.getChecked());
                    List<TreeDto> thirdTreeList = new ArrayList<>();
                    for (HnMenu thirdMenu : thirdMenuList) {
                        if (thirdMenu.getPid().equals(secondMenu.getId())) {
                            TreeDto thirdTree = new TreeDto();
                            thirdTree.setChecked(thirdMenu.getChecked());
                            thirdTree.setId(thirdMenu.getId());
                            thirdTree.setTitle(thirdMenu.getTitle());
                            thirdTreeList.add(thirdTree);
                        }
                    }
                    secondTree.setChildren(thirdTreeList);
                    secondTreeList.add(secondTree);
                }
            }
            firstTree.setChildren(secondTreeList);
            treeList.add(firstTree);
        }
        treeMap.put("idList",treeIdList);
        treeMap.put("treeList",treeList);
        return treeMap;
    }

    @Override
    public Result addRole(Authentication authentication, HnRole role) {
        role.setVersionNumber(0);
        roleMapper.insertReturn(role);
        List<String> treeIdList = role.getTreeList();
        if (CollectionUtils.isNotEmpty(treeIdList) && StringUtils.isNotBlank(treeIdList.get(0))) {
            String allTreeId = treeIdList.get(0);
            String[] treeId = allTreeId.split(",");
            List<HnRoleMenu> roleMenuList = new ArrayList<>();
            for (int i = 0; i < treeId.length; i++) {
                HnRoleMenu roleMenu = new HnRoleMenu();
                roleMenu.setRoleId(role.getRoleId());
                roleMenu.setMenuId(Integer.valueOf(treeId[i]));
                roleMenu.setVersionNumber(0);
                roleMenuList.add(roleMenu);
            }
            roleMenuMapper.insertList(roleMenuList);
            String key = RedisConstants.MENU_ROLE_CODE_KEY + role.getRoleId();
            stringRedisTemplate.delete(key);
        }
        return Result.success("添加成功");
    }

    @Override
    public Result updateRole(Authentication authentication, HnRole role) {
        if (null != role.getRoleId()) {
            roleMapper.updateByPrimaryKey(role);
            List<String> treeIdList = role.getTreeList();
            if (CollectionUtils.isNotEmpty(treeIdList) && StringUtils.isNotBlank(treeIdList.get(0))) {
                // 先删除再插入，保持数据正确
                roleMenuMapper.deleteByRoleId(role.getRoleId());
                String allTreeId = treeIdList.get(0);
                String[] treeId = allTreeId.split(",");
                List<HnRoleMenu> roleMenuList = new ArrayList<>();
                for (int i = 0; i < treeId.length; i++) {
                    HnRoleMenu roleMenu = new HnRoleMenu();
                    roleMenu.setRoleId(role.getRoleId());
                    roleMenu.setMenuId(Integer.valueOf(treeId[i]));
                    roleMenu.setVersionNumber(0);
                    roleMenuList.add(roleMenu);
                }
                roleMenuMapper.insertList(roleMenuList);
                String key = RedisConstants.MENU_ROLE_CODE_KEY + role.getRoleId();
                stringRedisTemplate.delete(key);
            }
            return Result.success("更新成功");
        }
        return Result.fail("更新失败");
    }

    @Override
    public Result deleteRole(Integer roleId) {
        try {
            // 删除角色菜单表数据
            roleMenuMapper.deleteByRoleId(roleId);
            // 删除角色表数据
            roleMapper.deleteByPrimaryKey(roleId);
            // 清除redis
            String key = RedisConstants.MENU_ROLE_CODE_KEY + roleId;
            stringRedisTemplate.delete(key);
        } catch (Exception e) {
            throw new RuntimeException("删除失败");
        }
        return Result.success("删除成功");
    }

    @Override
    public Result queryRole(HnRole role) {
        List<HnRole> roleList = roleMapper.selectByRoleName(role);
        return Result.querySuccess(roleList,roleList.size());
    }
}
